<template>
  <div class="common-crud" :style="{
    backgroundColor: dark ? '#1D1E1F' : '#fff',
    transition: 'all 0.2s',
  }">
    <!-- 搜索区域 -->
    <div class="search-card" v-if="showSearch">
      <el-form :inline="true" :model="searchForm">
        <slot name="search-form" :search-form="searchForm"></slot>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">查询</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <!-- 表格区域 -->
    <div class="table-card">
      <div class="card-header">
        <slot name="table-header"></slot>
      </div>

      <el-table :data="tableData" v-bind="tableProps" v-loading="loading">
        <slot></slot>
        <el-table-column v-if="showOperation" label="操作" :width="operationWidth">
          <template #default="scope">

            <slot name="operation" :row="scope.row" :index="scope.$index"></slot>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页器 -->
      <div class="pagination-container" v-if="showPagination">
        <el-pagination v-model:current-page="pageParams.page" v-model:page-size="pageParams.pageSize"
          :page-sizes="pageSizes" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange"
          layout="total, sizes, prev, pager, next, jumper" />
      </div>
    </div>


  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from "vue"
import { ElMessage, ElMessageBox } from "element-plus"
import { useSettingStore } from "@/stores/modules/setting"
import { storeToRefs } from "pinia"
const settingStore = useSettingStore()
const { dark } = storeToRefs(settingStore)

const props = defineProps({
  // 表格属性
  tableProps: {
    type: Object,
    default: () => ({}),
  },
  // 是否显示搜索
  showSearch: {
    type: Boolean,
    default: true,
  },
  // 是否显示操作列
  showOperation: {
    type: Boolean,
    default: true,
  },
  // 操作列宽度
  operationWidth: {
    type: String,
    default: "220",
  },
  // 是否显示分页
  showPagination: {
    type: Boolean,
    default: true,
  },
  // 分页大小选项
  pageSizes: {
    type: Array,
    default: () => [10, 20, 30, 50],
  },
})

const emit = defineEmits([
  "search",
  "reset",
  "add",
  "edit",
  "delete",
  "submit",
  "size-change",
  "current-change",
])

// 加载状态
const loading = ref(false)

// 表格数据
const tableData = ref([])

// 搜索表单
const searchForm = reactive({})

// 分页参数
const pageParams = reactive({
  page: 1,
  pageSize: 10,
})

// 总条数
const total = ref(0)



// 查询
const handleSearch = () => {
  pageParams.page = 1
  emit("search", { ...searchForm, ...pageParams })
}

// 重置
const resetSearch = () => {
  Object.keys(searchForm).forEach((key) => {
    searchForm[key] = ""
  })
  pageParams.page = 1
  emit("reset")
}




// 每页条数改变
const handleSizeChange = (val: number) => {
  pageParams.pageSize = val
  emit("size-change", val)
}

// 页码改变
const handleCurrentChange = (val: number) => {
  pageParams.page = val
  emit("current-change", val)
}
// 暴露方法和数据给父组件
defineExpose({
  searchForm,
  tableData,
  pageParams,
  total,
  loading,
  handleSearch,
  resetSearch,
})
</script>

<style scoped lang="scss">
.common-crud {
  height: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  padding: 30px;
  border-radius: 20px;

  .search-card {
    margin-bottom: 20px;
    flex-shrink: 0;
    padding: 20px;
    background-color: var(--el-bg-color);
    border-radius: 4px;
    border: 1px solid var(--el-border-color-light);
  }

  .table-card {
    flex: 1;
    display: flex;
    flex-direction: column;
    padding: 20px;
    background-color: var(--el-bg-color);
    border-radius: 4px;
    border: 1px solid var(--el-border-color-light);

    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20px;
    }

    .el-table {
      flex: 1;
    }

    .pagination-container {
      margin-top: 20px;
      display: flex;
      justify-content: flex-end;
      flex-shrink: 0;
    }
  }
}
</style>
</``` rewritten_file>